/*
 * Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.huawei.cloudphone.common;

import android.os.Parcel;
import android.os.Parcelable;

import com.huawei.cloudphone.BuildConfig;
import com.huawei.cloudphone.utils.CasAESUtils;

import java.util.Map;

import static com.huawei.cloudphone.utils.CasConstantsUtil.AES_KEY;
import static com.huawei.cloudphone.utils.CasConstantsUtil.AES_KEY_PATTERN;
import static com.huawei.cloudphone.utils.CasConstantsUtil.AUTH_TS;
import static com.huawei.cloudphone.utils.CasConstantsUtil.AVAILABLE_PLAYTIME;
import static com.huawei.cloudphone.utils.CasConstantsUtil.BACKGROUND_TIMEOUT;
import static com.huawei.cloudphone.utils.CasConstantsUtil.CLIENT_MODE;
import static com.huawei.cloudphone.utils.CasConstantsUtil.IP;
import static com.huawei.cloudphone.utils.CasConstantsUtil.IP_PATTERN;
import static com.huawei.cloudphone.utils.CasConstantsUtil.PORT;
import static com.huawei.cloudphone.utils.CasConstantsUtil.POSITIVE_NUMBER_PATTERN;
import static com.huawei.cloudphone.utils.CasConstantsUtil.REGION_ID;
import static com.huawei.cloudphone.utils.CasConstantsUtil.SESSION_ID;
import static com.huawei.cloudphone.utils.CasConstantsUtil.TICKET;
import static com.huawei.cloudphone.utils.CasConstantsUtil.TOUCH_TIMEOUT;
import static com.huawei.cloudphone.utils.CasConstantsUtil.USER_ID;

public class CasConnectorInfo implements Parcelable {

    public static final String BUNDLE_KEY = "CasConnectorInfo_Key";

    /**
     * 构造器
     */
    public static final Parcelable.Creator<CasConnectorInfo> CREATOR = new Parcelable.Creator<CasConnectorInfo>() {
        @Override
        public CasConnectorInfo createFromParcel(Parcel in) {
            return new CasConnectorInfo(in);
        }

        @Override
        public CasConnectorInfo[] newArray(int size) {
            return new CasConnectorInfo[size];
        }
    };

    /**
     * Bundle Key值
     */
    private static final String TAG = "CasConnectorInfo";

    /**
     * 连接ip
     */
    private String connectIp;

    /**
     * 连接端口
     */
    private String connectPort;

    /**
     * 连接sessionId
     */
    private String sessionId;

    /**
     * ticket信息(接入加密信息)
     */
    private String ticket;

    /**
     * 超时时长（home时长）, 单位秒级
     */
    private String backgroundTimeout;

    /**
     * 可玩时长，单位秒级
     */
    private String availablePlayTime;

    /**
     * 无触控时长，单位秒级
     */
    public String touchTimeout;

    /**
     * 验签时间戳
     */
    private String authTs;

    /**
     * 客户后台生成的对称秘钥
     */
    private String aesKey;

    /**
     * 加密盐
     */
    private String aesIv = CasAESUtils.getHexSalt();

    /**
     * sdk版本号
     */
    private String sdkVersion = BuildConfig.VERSION_NAME;

    /**
     * sdk与server通信协议版本
     */
    private String protocolVersion = "v2";

    /**
     * 用户ID
     */
    private String userID;


    /**
     * region ID
     */
    private String regionId;

    /**
     * client mode
     */
    private String clientMode;

    /**
     * 默认构造函数
     */
    public CasConnectorInfo() {
    }

    protected CasConnectorInfo(Parcel in) {
        connectIp = in.readString();
        connectPort = in.readString();
        sessionId = in.readString();
        ticket = in.readString();
        backgroundTimeout = in.readString();
        availablePlayTime = in.readString();
        authTs = in.readString();
        aesKey = in.readString();
        aesIv = in.readString();
        sdkVersion = in.readString();
        protocolVersion = in.readString();
        userID = in.readString();
        touchTimeout = in.readString();
        regionId = in.readString();
        clientMode = in.readString();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(connectIp);
        parcel.writeString(connectPort);
        parcel.writeString(sessionId);
        parcel.writeString(ticket);
        parcel.writeString(backgroundTimeout);
        parcel.writeString(availablePlayTime);
        parcel.writeString(authTs);
        parcel.writeString(aesKey);
        parcel.writeString(aesIv);
        parcel.writeString(sdkVersion);
        parcel.writeString(protocolVersion);
        parcel.writeString(userID);
        parcel.writeString(touchTimeout);
        parcel.writeString(regionId);
        parcel.writeString(clientMode);
    }

    public String getTicket() {
        return ticket;
    }

    public void setTicket(String ticket) {
        this.ticket = ticket;
    }

    public String getConnectIp() {
        return connectIp;
    }

    public void setConnectIp(String connectIp) {
        this.connectIp = connectIp;
    }

    public String getConnectPort() {
        return connectPort;
    }

    public void setConnectPort(String connectPort) {
        this.connectPort = connectPort;
    }

    public String getSessionId() {
        return sessionId;
    }

    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

    public String getAvailablePlayTime() {
        return availablePlayTime;
    }

    public void setAvailablePlayTime(String availablePlayTime) {
        this.availablePlayTime = availablePlayTime;
    }

    public String getBackgroundTimeout() {
        return backgroundTimeout;
    }

    public void setBackgroundTimeout(String backgroundTimeout) {
        this.backgroundTimeout = backgroundTimeout;
    }

    public String getAesKey() {
        return aesKey;
    }

    public void setAesKey(String aesKey) {
        this.aesKey = aesKey;
    }

    public String getAesIv() {
        return aesIv;
    }

    public void setAesIv(String aesIv) {
        this.aesIv = aesIv;
    }

    public String getAuthTs() {
        return authTs;
    }

    public void setAuthTs(String authTs) {
        this.authTs = authTs;
    }

    public String getSdkVersion() {
        return sdkVersion;
    }

    public void setSdkVersion(String sdkVersion) {
        this.sdkVersion = sdkVersion;
    }

    public String getProtocolVersion() {
        return protocolVersion;
    }

    public void setProtocolVersion(String protocolVersion) {
        this.protocolVersion = protocolVersion;
    }

    public String getUserId() {
        return userID;
    }

    public void setUserId(String userId) {
        userID = userId;
    }

    public String getTouchTimeout() {
        return touchTimeout;
    }

    public void setTouchTimeout(String timeout) {
        touchTimeout = timeout;
    }

    public String getRegionId() {
        return regionId;
    }

    public void setRegionId(String regionId) {
        this.regionId = regionId;
    }

    public String getClientMode() {
        return clientMode;
    }

    public void setClientMode(String clientMode) {
        this.clientMode = clientMode;
    }

    /**
     * check start params
     * <p>check params</p>
     */
    public boolean initConnectorParams(Map<String, String> params) {
        String ip = params.get(IP);
        if (ip == null || !IP_PATTERN.matcher(ip).matches()) {
            CASLog.i(TAG, "Parameter: ip is invalid.");
            return false;
        }

        String port = params.get(PORT);
        if (port == null || !POSITIVE_NUMBER_PATTERN.matcher(port).matches()) {
            CASLog.i(TAG, "Parameter: port is invalid.");
            return false;
        }

        String sessionId = params.get(SESSION_ID);
        if (sessionId == null) {
            CASLog.i(TAG, "Parameter: session_id is invalid.");
            return false;
        }

        String ticket = params.get(TICKET);
        if (ticket == null) {
            CASLog.i(TAG, "Parameter: ticket is invalid.");
            return false;
        }

        String aesKey = params.get(AES_KEY);
        if (aesKey == null || !AES_KEY_PATTERN.matcher(aesKey).matches()) {
            CASLog.i(TAG, "Parameter: aes_key is invalid.");
            return false;
        }

        String authTs = params.get(AUTH_TS);
        if (authTs == null) {
            CASLog.i(TAG, "Parameter: auth_ts is invalid.");
            return false;
        }

        String clientMode = params.get(CLIENT_MODE);
        if (clientMode == null) {
            CASLog.i(TAG, "Parameter: clientMode is invalid.");
            return false;
        }

        String backgroundTimeout = params.get(BACKGROUND_TIMEOUT);
        if (backgroundTimeout == null || backgroundTimeout.length() == 0) {
            backgroundTimeout = "60";
        } else {
            try {
                int timeOut = Integer.parseInt(backgroundTimeout);
                if (timeOut < 15 || timeOut > 3600) {
                    backgroundTimeout = "60";
                }
            } catch (NumberFormatException e) {
                CASLog.e(TAG, "Parameter: background_timeout is invalid.");
                return false;
            }
        }

        String availablePlaytime = params.get(AVAILABLE_PLAYTIME);
        if (availablePlaytime == null) {
            availablePlaytime = "0";
        }

        String userId = params.get(USER_ID);
        if (userId == null) {
            userId = "";
            CASLog.i(TAG, "Parameter: userId is null.");
        }

        String touchTimeOut = params.get(TOUCH_TIMEOUT);
        if (touchTimeOut == null || touchTimeOut.length() == 0) {
            touchTimeOut = "0";
        } else {
            try {
                int timeOut = Integer.parseInt(touchTimeOut);
                if (timeOut < 0) {
                    touchTimeOut = "0";
                }
            } catch (NumberFormatException e) {
                CASLog.e(TAG, "touch_timeout value invalid. " + touchTimeOut);
                return false;
            }
        }

        String regionId = params.get(REGION_ID);
        if (regionId == null) {
            regionId = "";
        }

        setConnectIp(ip);
        setConnectPort(port);
        setBackgroundTimeout(backgroundTimeout);
        setAvailablePlayTime(availablePlaytime);
        setTicket(ticket);
        setSessionId(sessionId);
        setAuthTs(authTs);
        setAesKey(aesKey);
        setUserId(userId);
        setSdkVersion(BuildConfig.VERSION_NAME);
        setTouchTimeout(touchTimeOut);
        setRegionId(regionId);
        setClientMode(clientMode);
        return true;
    }
}
